package com.wh1200.mybatis.xmlless

import com.baomidou.mybatisplus.extension.parser.JsqlParserGlobal
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter
import net.sf.jsqlparser.parser.CCJSqlParser
import net.sf.jsqlparser.parser.CCJSqlParserUtil
import net.sf.jsqlparser.parser.SimpleNode
import net.sf.jsqlparser.schema.Column
import net.sf.jsqlparser.schema.Table
import net.sf.jsqlparser.statement.select.PlainSelect
import net.sf.jsqlparser.statement.select.Select
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals

/**
 *
 * @author 吴昊
 * @date 2023/12/13 20:42
 * @since v4.0.0
 * @version 1.0
 */
class SqlParser {

  @Test
  fun parse2() {
    val sql = """UPDATE
  xmlless.t_student
   SET name=?,
age=?,
grade=?,
favorites=?,
sex=?,
graduated=?,
phone_number=?,
del_flag=?,
state=? 
        WHERE id = ?
"""
    CCJSqlParser(sql).Statement()

    JsqlParserGlobal.parse(sql)
    CCJSqlParserUtil.parse(
        sql
    )
  }

  @Test
  fun parsePostgreSQLCast() {
    val exp = CCJSqlParser("(t_student.detail->'height')::integer").Expression()
    println(exp)
  }

  @Test
  fun parse() {
    val s = "SELECT 1 FROM A LEFT JOIN DateConfig a ON date_format(a.date, '%Y-%m-%d') = " +
        "date_format(createTime, '%Y-%m-%d') and a.name = configName"
    val node = CCJSqlParserUtil.parseAST(s)
    node.jjtAccept({ simpleNode: SimpleNode, _: Any? ->
      simpleNode
    }, null)
    val a = CCJSqlParserUtil.parse(s) as Select
    val body = a.selectBody as PlainSelect
    val join = body.joins.first()
    val joinTable = join.rightItem as Table
    println(joinTable.name + "/" + joinTable.alias)
    join.onExpressions.forEach {
      it.accept(object : ExpressionVisitorAdapter() {

        override fun visit(column: Column) {
          println(column)
          println(column.table?.name + "/" + column.table?.alias)
        }

      })
    }
    println(join)
  }

  @Test
  fun a() {
    val exp = "if type = 1 then a like b"
    val ifBuilder = StringBuilder()
    var ifEnded = false
    val sqlBuilder = StringBuilder()
    val wordList = exp.split("\\s+".toRegex())
    if (wordList.first().lowercase() !in listOf("if", "when")) {
      throw IllegalArgumentException("表达式必须以if或when开头")
    }
    wordList.drop(1).forEach {
      if (it.lowercase() == "then") {
        ifEnded = true
      } else if (ifEnded) {
        sqlBuilder.append(it).append(" ")
      } else {
        ifBuilder.append(it).append(" ")
      }
    }
    assertEquals("type = 1", ifBuilder.toString().trim())
    assertEquals("a like b", sqlBuilder.toString().trim())
  }

}
